// SPDX-FileCopyrightText: Copyright 2025-2025 深圳市同心圆网络有限公司
// SPDX-License-Identifier: GPL-3.0-only

package manifest_impl

import (
	"encoding/json"
	"time"

	"gitcode.com/openseaotter/so_proto_gen_go.git/image_api"
)

//application/vnd.docker.container.image.v1+json
//https://github.com/moby/docker-image-spec/blob/v1.2.0/v1.2.md

type DockerImageHealthcheck struct {
	Test     []string `json:"Test"`
	Interval int64    `json:"Interval"`
	Timeout  int64    `json:"Timeout"`
	Retries  int      `json:"Retries"`
}

type DockerImageConfig struct {
	User         string                 `json:"User"`
	Memory       int64                  `json:"Memory"`
	MemorySwap   int64                  `json:"MemorySwap"`
	CpuShares    int                    `json:"CpuShares"`
	ExposedPorts map[string]any         `json:"ExposedPorts,omitempty"`
	Env          []string               `json:"Env,omitempty"`
	Entrypoint   []string               `json:"Entrypoint,omitempty"`
	Cmd          []string               `json:"Cmd,omitempty"`
	ArgsEscaped  bool                   `json:"ArgsEscaped"`
	Healthcheck  DockerImageHealthcheck `json:"Healthcheck"`
	Volumes      map[string]any         `json:"Volumes,omitempty"`
	WorkingDir   string                 `json:"WorkingDir"`
	OnBuild      []string               `json:"OnBuild,omitempty"`
	Shell        []string               `json:"Shell,omitempty"`
}

type DockerImageSpec struct {
	Created      string            `json:"created"`
	Author       string            `json:"author"`
	Architecture string            `json:"architecture"`
	Os           string            `json:"os"`
	Config       DockerImageConfig `json:"config"`
	Rootfs       ImageRootfs       `json:"rootfs"`
	History      []ImageHistory    `json:"history,omitempty"`
}

func (dc *DockerImageSpec) ToProto() (*image_api.ImageConfig, error) {
	created, err := time.Parse(time.RFC3339Nano, dc.Created)
	if err != nil {
		return nil, err
	}
	exposedPorts := map[string]string{}
	for k, v := range dc.Config.ExposedPorts {
		value, err := json.Marshal(v)
		if err != nil {
			return nil, err
		}
		exposedPorts[k] = string(value)
	}
	volumes := map[string]string{}
	for k, v := range dc.Config.Volumes {
		value, err := json.Marshal(v)
		if err != nil {
			return nil, err
		}
		volumes[k] = string(value)
	}
	return &image_api.ImageConfig{
		Created:      created.UnixMilli(),
		Author:       dc.Author,
		Architecture: dc.Architecture,
		Os:           dc.Os,
		Config: &image_api.ImageConfig_Config{
			User:         dc.Config.User,
			ExposedPorts: exposedPorts,
			Env:          dc.Config.Env,
			Entrypoint:   dc.Config.Entrypoint,
			Cmd:          dc.Config.Cmd,
			Volumes:      volumes,
			WorkingDir:   dc.Config.WorkingDir,
			Labels:       map[string]string{},
		},
	}, nil
}
